package com.qingcheng.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.qingcheng.pojo.goods.Category;
import com.qingcheng.pojo.goods.Sku;
import com.qingcheng.pojo.order.OrderItem;
import com.qingcheng.service.goods.CategoryService;
import com.qingcheng.service.goods.SkuService;
import com.qingcheng.service.order.CartService;
import com.qingcheng.service.order.PreferentialService;
import com.qingcheng.utils.CacheKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import tk.mybatis.mapper.entity.Example;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class CartServiceImpl implements CartService {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 添加购物车
     *
     * @param userName
     * @return
     */
    @Override
    public List<Map<String, Object>> findCartList(String userName) {
        //从redis中找该用户的购物车,一个购物车就是一个list
        List<Map<String, Object>> cartList = (List<Map<String, Object>>) redisTemplate.boundHashOps(CacheKey.CART_LIST).get(userName);
        if (cartList == null) {
            //如果购物车不在缓存中,就新建一个list
            return new ArrayList<>();
        }
        return cartList;
    }

    @Reference
    private SkuService skuService;
    @Reference
    private CategoryService categoryService;

    /**
     * 添加商品到购物车
     * 遍历购物车,如果购物车中有商品,就累加数量,如果没有就增加商品
     *
     * @param userName
     * @param skuId
     * @param num
     */
    @Override
    public void addItem(String userName, String skuId, Integer num) {
        List<Map<String, Object>> cartList = findCartList(userName); //获得购物车
        boolean flag = false; //购物车中是否有商品
        for (Map<String, Object> map : cartList) { //遍历购物车,获得map集合,集合中有item:OrderItem类型,商品详细  checked:布尔类型,是否选中
            OrderItem item = (OrderItem) map.get("item");
            if (skuId.equals(item.getSkuId())) { //如果购物车中存在该商品
                if (item.getNum() <= 0) { //如果商品数量小于等于0,就从购物车中移除
                    cartList.remove(map);
                    flag = true;
                    break;
                }
                int singleWeight = item.getWeight() / item.getNum(); //原来单个商品的重量
                item.setNum(item.getNum() + num); //设置商品数量
                item.setWeight(item.getNum() * singleWeight); //设置商品的总重量
                item.setMoney(item.getNum() * item.getPrice()); //设置商品总价格
                if (item.getNum() <= 0) { //如果商品数量小于等于0,就从购物车中移除
                    cartList.remove(map);
                }
                flag = true;
                break;
            }
        }
        if (!flag) { //如果购物车中没有商品
            Sku sku = skuService.findById(skuId); //通过id找到对应的sku
            if (sku == null)
                throw new RuntimeException("该商品不存在!");
            if (!"1".equals(sku.getStatus()))
                throw new RuntimeException("商品状态不合法!");
            if (num <= 0) //商品数量不能小于等于0
                throw new RuntimeException("商品数量不合法!");
            //添加商品详情到OrderItem中
            OrderItem item = new OrderItem();
            item.setSkuId(skuId);
            item.setSpuId(sku.getSpuId());
            item.setNum(num);
            item.setImage(sku.getImage());
            item.setPrice(sku.getPrice());
            item.setName(sku.getName());
            item.setMoney(item.getPrice() * num);
            if (sku.getWeight() == null) {
                sku.setWeight(0);
            }
            item.setWeight(sku.getWeight() * num);
            //商品分类
            item.setCategoryId3(sku.getCategoryId());
            Category category3 = (Category) redisTemplate.boundHashOps(CacheKey.CATEGORY).get(sku.getCategoryId()); //从缓存中找category3
            if (category3 == null) { //如果没找到,通过id找category3,并存入缓存中
                category3 = categoryService.findById(sku.getCategoryId());
                redisTemplate.boundHashOps(CacheKey.CATEGORY).put(sku.getCategoryId(), category3);
            }
            item.setCategoryId2(category3.getParentId()); //通过category3找到父id,即2级id
            Category category2 = (Category) redisTemplate.boundHashOps(CacheKey.CATEGORY).get(category3.getParentId()); //从缓存中找category2
            if (category2 == null) { //如果没找到,通过id找category2,并存入缓存中
                category2 = categoryService.findById(category3.getParentId());
                redisTemplate.boundHashOps(CacheKey.CATEGORY).put(category3.getParentId(), category2);
            }
            item.setCategoryId1(category2.getParentId()); //通过category2找到父id,即1级id
            Category category1 = (Category) redisTemplate.boundHashOps(CacheKey.CATEGORY).get(category2.getParentId()); //从缓存中找category1
            if (category1 == null) { //如果没找到,通过id找category1,并存入缓存中
                category1 = categoryService.findById(category2.getParentId());
                redisTemplate.boundHashOps(CacheKey.CATEGORY).put(category2.getParentId(), category1);
            }
            Map<String, Object> map = new HashMap();
            map.put("item", item);
            map.put("checked", true); //默认选中
            cartList.add(map);
        }
        redisTemplate.boundHashOps(CacheKey.CART_LIST).put(userName, cartList); //把购物车放入缓存中
    }

    /**
     * 更新勾选状态
     *
     * @param userName
     * @param skuId
     * @param checked
     * @return
     */
    @Override
    public boolean updateChecked(String userName, String skuId, boolean checked) {
        //找到该用户的购物车
        List<Map<String, Object>> cartList = findCartList(userName);
        //定义是否更新
        boolean isOk = false;
        for (Map<String, Object> map : cartList) {
            OrderItem item = (OrderItem) map.get("item");
            if (skuId.equals(item.getSkuId())) { //说明有找到了这个sku
                map.put("checked", checked); //更新勾选状态
                isOk = true;
                break;
            }
        }
        if (isOk) {
            //如果更新了勾选状态,就同时更新缓存中的购物车
            redisTemplate.boundHashOps(CacheKey.CART_LIST).put(userName, cartList);
        }
        return isOk;
    }

    /**
     * 删除购物车中选中商品
     *
     * @param userName
     */
    @Override
    public void deleteCheckedCart(String userName) {
       /* List<Map<String, Object>> cartList = findCartList(userName);
        for (Map<String, Object> map : cartList) {
            if((boolean)map.get("checked") == false) { //如果未被选中
                cartList.remove(map);
            }
        }*/
        List<Map<String, Object>> cartList = findCartList(userName).stream()
                .filter(cart -> !(boolean) cart.get("checked"))
                .collect(Collectors.toList());
        redisTemplate.boundHashOps(CacheKey.CART_LIST).put(userName, cartList);
    }

    @Autowired
    private PreferentialService preferentialService;

    /**
     * 计算当前选中的购物车的优惠金额
     *
     * @param userName
     * @return
     */
    @Override
    public int preferential(String userName) {
        //获取选中的购物车
        List<OrderItem> orderItemList = findCartList(userName).stream()
                .filter(cart -> (boolean) cart.get("checked"))
                .map(cart -> (OrderItem) cart.get("item"))
                .collect(Collectors.toList());
        //按分类聚合统计每个分类的金额
        Map<Integer, IntSummaryStatistics> cartMap = orderItemList.stream()
                .collect(Collectors.groupingBy(OrderItem::getCategoryId3,
                        Collectors.summarizingInt(OrderItem::getMoney)));
        //循环结果,统计每个分类的优惠金额,并累加
        int allPreMoney = 0;
        for (Integer categoryId : cartMap.keySet()) {
            //获取品类的消费金额
            int money = (int) cartMap.get(categoryId).getSum();
            //优惠金额
            int preMoney = preferentialService.findPreMoneyByCategoryId(categoryId, money);
            System.out.println("分类：" + categoryId + " 消费金额：" + money + "优惠金额: " + preMoney);
            allPreMoney += preMoney;
        }
        return allPreMoney;
    }

    /**
     * 重新查找购物车
     *
     * @param userName
     * @return
     */
    @Override
    public List<Map<String, Object>> findNewCartList(String userName) {
        List<Map<String, Object>> cartList = findCartList(userName);
        for (Map<String, Object> map : cartList) {
            OrderItem item = (OrderItem) map.get("item");
            Sku sku = skuService.findById(item.getSkuId());
            //重新设置单价和总金额
            item.setPrice(sku.getPrice());
            item.setMoney(sku.getPrice()*item.getNum());
        }
        redisTemplate.boundHashOps(CacheKey.CART_LIST).put(userName,cartList);
        return cartList;
    }
}
